import json,re,jieba
import jieba                  # jieba分词
import difflib                # 方法一：Python自带标准库计算相似度的方法，可直接用
from fuzzywuzzy import fuzz   # 方法二：Python自带标准库计算相似度的方法，可直接用
import numpy as np
from collections import Counter
import re
import copy
from functools import reduce
from loc_s import get_loc

# 方法三：编辑距离，又称Levenshtein距离
def edit_similar(str1, str2):   # str1，str2是分词后的标签列表
    len_str1 = len(str1)
    len_str2 = len(str2)
    taglist = np.zeros((len_str1+1, len_str2+1))
    for a in range(len_str1):
        taglist[a][0] = a
    for a in range(len_str2):
        taglist[0][a] = a
    for i in range(1, len_str1+1):
        for j in range(1, len_str2+1):
            if(str1[i - 1] == str2[j - 1]):
                temp = 0
            else:
                temp = 1
            taglist[i][j] = min(taglist[i - 1][j - 1] + temp, taglist[i][j - 1] + 1, taglist[i - 1][j] + 1)
    return 1-taglist[len_str1][len_str2] / max(len_str1, len_str2)

# 方法四：余弦相似度
def cos_sim(str1, str2):        # str1，str2是分词后的标签列表
    co_str1 = (Counter(str1))
    co_str2 = (Counter(str2))
    p_str1 = []
    p_str2 = []
    for temp in set(str1 + str2):
        p_str1.append(co_str1[temp])
        p_str2.append(co_str2[temp])
    p_str1 = np.array(p_str1)
    p_str2 = np.array(p_str2)
    return p_str1.dot(p_str2) / (np.sqrt(p_str1.dot(p_str1)) * np.sqrt(p_str2.dot(p_str2)))
#print(k3)
"""
with open('dict.txt', 'w', encoding='utf-8') as f:
    json.dump(k3, f, ensure_ascii=False)
"""
#规范版本比对函数（进行了修改）
def gfvs(s,g):
    flg=[0 for i in range(len(s))]
    i=0
    
    for k in s.keys():
        for k_g in g.keys():
                if j_words(k,k_g,1)>=flg[i]:flg[i]=j_words(k,k_g,1);k_tem=k_g
        if flg[i]==1:
            #print(k,s[k],"版本已找到")
            if g[k]==s[k]:
                print(k,s[k],"----查表正确----√")

            elif s[k]=="":print(k,s[k],"查表结果为:",g[k])
            else :print(k,s[k],"###查表错误####,正确为:",g[k])
        elif flg[i]>0.6:
            if g[k_tem]==s[k]:
                print(k,s[k],f"----大概率正确---√,可能为:{k_tem},{g[k_tem]}")
            elif s[k]=="":print(k,s[k],"大概率查表结果为:",k_tem,g[k_tem])
            else:print(k,s[k],f"###大概率错误####,大概率正确正确为:{k_tem},{g[k_tem]}")
        else:
            print(k,s[k],f"##########库中未找到对应条目#########,可能为:{k_tem},{g[k_tem]}")
        i+=1
    print(flg)
    return flg
#自编的判断短语近似度的函数，低于阈值返回零，大于阈值返回相关值，如果可选参数有值，将不管阈值全部输出比较值。
def j_words(str1,str2,*k):
    k0=1 if k else 0
    str11 = jieba.lcut(str1)
    str22 = jieba.lcut(str2)
    g_flg=0
    diff_result = difflib.SequenceMatcher(None, str1, str2).ratio()
    diff_rb=min(diff_result,fuzz.ratio(str1, str2)/100)
    diff_rc=min(cos_sim(str11, str22),edit_similar(str11, str22))
    diff_ra=max(diff_rb,diff_rc)
    diff_rd=max(diff_result,fuzz.ratio(str1, str2)/100,cos_sim(str11, str22),edit_similar(str11, str22))
    if (diff_ra>0.30 and diff_rd>0.45) or diff_ra>0.35:
        #print(f"两句话有比较相近的关联程度，相似度ra={diff_ra},相似度rd={diff_rd}")
        g_flg=diff_ra
    else:
        #print("两句话没啥关系")
        g_flg=g_flg*k0
    return g_flg

#把键值为多个主体词用顿号隔开的复杂字典变成简单字典
def dmtods(d2):
    d3={}
    for s1 in d2.keys():
        for k1 in re.split("、",s1):
            d3[k1]=d2[s1]
    return d3


#把字符格式的元组复原
def _str2tuple(key):
    # 注意python切片 左开右闭 的性质
	
    key_tem = key[1:-1]
    key_tem=re.split(",",key_tem)
    return tuple(key_tem)

#读取风雪烈度抗震等级数据库
def fxzgf():
    with open('风压.txt', 'r', encoding='utf-8') as f:
        fy= json.load(f)
    with open('雪压.txt', 'r', encoding='utf-8') as f:
        xy= json.load(f)
    with open('设防烈度.txt', 'r', encoding='utf-8') as f:
        ld= json.load(f)
    with open('抗震等级.txt', 'r', encoding='utf-8') as f:
        kz = json.load(f)
        kz1 ={_str2tuple(k): kz[k] for k in kz}
    return(fy,xy,ld,(kz,kz1))

#搜索出来的结构形式，设防烈度，建筑高度 转成可以搜索key的元组或者字符串
def kztos(strs,kz1):
    t=[]
    jg_bf= [(st in strs) for st in ["剪力墙","剪力墙结构","抗震墙"]]
    jg_bf=reduce(lambda x,y:x or y,jg_bf)
    t.append("抗震墙") if jg_bf else t.append('不明结构')
    ld=re.search("\d度", strs)
    t.append(ld.group()) if ld else t.append('不明烈度')
    gd=float(re.search("\d\d\.\d\d", strs).group())
    #print(jg_bf,ld)
    if ld and jg_bf :
        for k in kz1.keys():
            if t[0]==k[0] and t[1]==k[1]:
                if "《" in k[2] :
                    if gd<float(re.search("\d\d", k[2]).group()):t.append(k[2])
                elif "~"  in k[2] :
                    if float(k[2][:2])<gd and gd<float(k[2][k[2].index("~")+1:]):t.append(k[2])   
    if len(t)==2:t.append(str(gd))
    s='('+t[0]+','+t[1]+','+t[2]+')'
    return (tuple(t),s)

#根据县城查找所属地市
def xfroms(xc):
    with open('县市关系.txt', 'r', encoding='utf-8') as f:
        x_city= json.load(f)
        xcs=dmtods(x_city)
        #print(xcs)
        #print(xcs["汤阴县"])
        r_c="不明城市"
        for k in xcs.keys():
            if xc in k: 
                r_c=xcs[k] 
    return r_c
        

if __name__=='__main__':
    fy,xy,ld,kz=fxzgf()

    #print(ld)
    gfvs({kztos("剪力墙，6度，35.01",kz[1])[1]:""},kz[0])

    loc=get_loc("项目位于偃师市")

    print(loc[0]+"属于"+xfroms(loc[0]));gfvs({xfroms(loc[0]):""},fy) if gfvs({loc[0]:""},fy)[0]<0.9 else gfvs({loc[0]:""},fy)
    gfvs({loc[0]:""},dmtods(ld))

